/*
 * @Author: 肖思汗 
 * @Date: 2020-07-29 00:38:28 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2021-06-06 14:23:43
 */

import { createHashHistory } from "history";
import _ from 'lodash';
import { autorun, IReactionDisposer } from 'mobx';
import * as React from 'react';
import { ErrorInfo } from 'react';
import mixin_emitter from './mixin_emitter';
import utils from './utils';

// js 也可以引用
export const mixin_history = createHashHistory({ basename: 'basename' });

/**
 * 统一处理所有组件的需求
 * 
 * @export
 * @class ReactMixinComponent
 * @extends {React.Component<Props, State>}
 * @implements {ReactMixinComponentInstance<Props, State>}
 * @template Props
 * @template State
 */
export default class ReactMixinComponent<Props, State> extends React.Component<Props, State>{

    constructor(props: Props) {
        super(props);

        //混入mixin_componentDidMount生命周期
        let originComponentDidMount = this.componentDidMount;
        this.componentDidMount = function () {
            this.mixin_componentDidMount.apply(this);
            if (originComponentDidMount) {
                originComponentDidMount.apply(this);
            }
        }

        //混入mixin_componentDidUpdate生命周期
        let originComponentDidUpdate = this.componentDidUpdate;
        this.componentDidUpdate = function (nextProps: Readonly<Props>, nextState: Readonly<State>, snapshot: any) {
            this.mixin_componentDidUpdate.apply(this, [nextProps, nextState, snapshot]);
            if (originComponentDidUpdate) {
                originComponentDidUpdate.apply(this, [nextProps, nextState, snapshot]);
            }
        }

        //混入mixin_componentDidCatch生命周期
        let originComponentDidCatch = this.componentDidCatch;
        this.componentDidCatch = function (error: Error, errorInfo: ErrorInfo) {
            this.mixin_componentDidCatch.apply(this, [error, errorInfo]);
            if (originComponentDidCatch) {
                originComponentDidCatch.apply(this, [error, errorInfo]);
            }
        }

        //混入mixin_componentWillUnmount生命周期
        let originComponentWillUnmount = this.componentWillUnmount;
        this.componentWillUnmount = function () {
            this.mixin_componentWillUnmount.apply(this);
            if (originComponentWillUnmount) {
                originComponentWillUnmount.apply(this);
            }
        }


    }

    // 组件是否安装完成
    isMount = false;

    // mobx 自动执行的实例对象
    mobxAutorunInstances: IReactionDisposer[] = [];

    // 全局路由
    mixin_history = mixin_history;

    // 全局事件分发对象
    mixin_emitter = new mixin_emitter();

    //公共方法
    utils = utils;

    // 当前组件的mobx 监听全局状态的方法
    mixin_autorun(callback: () => void) {
        this.mobxAutorunInstances.push(autorun(callback));
    }

    // react 推荐使用的生命周期
    mixin_componentDidMount(): void {
        this.isMount = true;
    }

    mixin_componentDidUpdate(prevProps: Readonly<Props>, prevState: Readonly<State>, snapshot: string): void {

    }

    // 判断组件是否重绘的默认规则
    shouldComponentUpdate(nextProps: Readonly<Props>, nextState: Readonly<State>, nextContext: any): boolean {
        return (
            !_.isEqual(this.props, nextProps) ||
            !_.isEqual(this.state, nextState)
        );
    }

    // 组件异常捕获
    mixin_componentDidCatch(error: Error, errorInfo: ErrorInfo): void {

    }

    // 当组件卸载时对组件进行清理
    mixin_componentWillUnmount() {
        // 避免在组件卸载后异步调用此方法而报错
        this.setState = () => { };

        // 销毁mobx 的监听
        this.mobxAutorunInstances.map(instance => instance());

        // 删除此组件上的所有监听事件
        this.mixin_emitter.removeAll();

        this.isMount = false;
    }
}